/* hzf */
#include "CdUart1.h"
#include "S32K144.h"
#include "S32K144_features.h"
#include "MdLink.h"

/* Init. summary: 115200 baud, 1 stop bit, 8 bit format, no parity */
static void LPUART0_init(void)
{
	PCC->PCCn[PCC_LPUART0_INDEX] &= ~PCC_PCCn_CGC_MASK;
	PCC->PCCn[PCC_LPUART0_INDEX] |= PCC_PCCn_PCS(1) | PCC_PCCn_CGC_MASK;

	LPUART0->BAUD = LPUART_BAUD_SBR(15) | LPUART_BAUD_OSR(22);
	LPUART0->FIFO = LPUART_FIFO_RXFE(1) | LPUART_FIFO_TXFE(1) ;
	LPUART0->CTRL = LPUART_CTRL_RE(1) | LPUART_CTRL_TE(1);
}

static void LPUART1_init(void)
{
	PCC->PCCn[PCC_LPUART1_INDEX] &= ~PCC_PCCn_CGC_MASK;
	PCC->PCCn[PCC_LPUART1_INDEX] |= PCC_PCCn_PCS(1) | PCC_PCCn_CGC_MASK;

	LPUART1->BAUD = LPUART_BAUD_SBR(15) | LPUART_BAUD_OSR(22);
	LPUART1->FIFO = LPUART_FIFO_RXFE(1) | LPUART_FIFO_TXFE(1) ;
	LPUART1->CTRL = LPUART_CTRL_RE(1) | LPUART_CTRL_TE(1);
}

static void PORT_init_LPUART(void)
{
	PCC->PCCn[PCC_PORTC_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTC */
	PORTC->PCR[6]|=PORT_PCR_MUX(2); 		  /* Port C6: MUX = ALT2,UART1 RX */
	PORTC->PCR[7]|=PORT_PCR_MUX(2); 		  /* Port C7: MUX = ALT2,UART1 TX */

	PCC->PCCn[PCC_PORTB_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTC */
	PORTB->PCR[0]|=PORT_PCR_MUX(2);	/* Port C6: MUX = ALT2, UART1 TX */
	PORTB->PCR[1]|=PORT_PCR_MUX(2);   /* Port C7: MUX = ALT2, UART1 RX */
}

void UART_Init(void)
{
	PORT_init_LPUART();
	LPUART0_init();
	LPUART1_init();
}

//uint8_t uart0OverflowCnt = 0;
//uint8_t uart0ReadCnt = 0;
void UART0_Polling_Read(void)
{
	uint8_t recieve;
	uint16_t timeout = 0;
	uint32_t rxcount = LPUART0->WATER;

	if ((LPUART0->STAT & LPUART_STAT_OR_MASK)>>LPUART_STAT_OR_SHIFT == 1) {
		//uart0OverflowCnt++;
		LPUART0->STAT |= LPUART_STAT_OR(1);
	}

	if ((rxcount & LPUART_FIFO_RXEMPT_MASK)>>LPUART_FIFO_RXEMPT_SHIFT == 0) {
		while ((LPUART0->WATER & LPUART_WATER_RXCOUNT_MASK)>>LPUART_WATER_RXCOUNT_SHIFT > 0) {

			//uart0ReadCnt++;
			recieve = (uint8_t)LPUART0->DATA;
			//UART0_Write_Byte(recieve);
			mid_link_set_receive_data_buf((uint8_t)recieve); 
		}
	}
}

uint8_t UART0_Write_Byte(uint8_t data)
{
	while((LPUART0->STAT & LPUART_STAT_TDRE_MASK)>>LPUART_STAT_TDRE_SHIFT==0);
  	LPUART0->DATA=data;
}

void UART0_Write_Buf(uint8_t *buf, uint16_t bufLen)
{
	uint8_t index = 0;
	while (bufLen > 0) {
		UART0_Write_Byte(buf[index++]);
		bufLen--;
	}
	// UART0_Write_Byte('\r');
	// UART0_Write_Byte('\n');
}

#define DISABLE_LOG 1

#include "stdarg.h"
#include "string.h"
// extern MsTick msTick;
const uint8_t hexToAsc[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void LogString(char *str)
{
	uint8_t index = 3;
	uint32_t cv;
	uint8_t h;
	uint8_t l;

#if (defined(DISABLE_LOG) && (DISABLE_LOG == 1))
	return;
#endif
	// UART0_Write_Byte('[');
	// while (1) {
	// 	h = (msTick.msByte[index] & 0xF0)>>4;
	// 	l = (msTick.msByte[index] & 0x0F);
	// 	UART0_Write_Byte(hexToAsc[h]);
	// 	UART0_Write_Byte(hexToAsc[l]);
	// 	if (index == 0) {
	// 		break;
	// 	}
	// 	index--;
	// }

	// UART0_Write_Byte(']');

	while (*str != '%' && *str != '\0') {
		UART0_Write_Byte(*str);
		str++;
	}
	UART0_Write_Byte('\r');
	UART0_Write_Byte('\n');
}

void LogBuf(uint8_t *buf, uint16_t bufLen)
{
	uint8_t h;
	uint8_t l;
#if (defined(DISABLE_LOG) && (DISABLE_LOG == 1))
	return;
#endif
	for (uint8_t index = 0; index < bufLen; index++) {
		h = (buf[index] & 0xF0)>>4;
		l = (buf[index] & 0x0F);
		UART0_Write_Byte(hexToAsc[h]);
		UART0_Write_Byte(hexToAsc[l]);
		UART0_Write_Byte(' ');
	}
	UART0_Write_Byte('\r');
	UART0_Write_Byte('\n');
}

uint8_t uart1OverflowCnt = 0;
uint8_t uart1ReadCnt = 0;
void UART1_Polling_Read(void)
{
	uint8_t receive;
	uint16_t timeout = 0;
	uint32_t rxcount = LPUART1->WATER;

	if ((LPUART1->STAT & LPUART_STAT_OR_MASK)>>LPUART_STAT_OR_SHIFT == 1) {
		uart1OverflowCnt++;
		LPUART1->STAT |= LPUART_STAT_OR(1);
	}

	if ((LPUART0->STAT & LPUART_STAT_OR_MASK)>>LPUART_STAT_OR_SHIFT == 1) {
		uart1OverflowCnt++;
		LPUART0->STAT |= LPUART_STAT_OR(1);
	}

	if ((rxcount & LPUART_FIFO_RXEMPT_MASK)>>LPUART_FIFO_RXEMPT_SHIFT == 0) {
		while ((LPUART1->WATER & LPUART_WATER_RXCOUNT_MASK)>>LPUART_WATER_RXCOUNT_SHIFT > 0) {
			uart1ReadCnt++;
			receive = (uint8_t)LPUART1->DATA;
			UART0_Write_Byte(receive);
			mid_link_set_receive_data_buf((uint8_t)receive); 
		}
	}
}

uint8_t UART1_Write_Byte(uint8_t data)
{
	while((LPUART1->STAT & LPUART_STAT_TDRE_MASK)>>LPUART_STAT_TDRE_SHIFT==0);
  	LPUART1->DATA=data;	
	return 1;
}

#if 0
void LogSimple(char *str, ...)
{
	uint8_t index = 0;
	uint8_t buf[16];
	uint32_t cv;
	va_list va;
	va_start(va, str);
	while (*str != '%' && *str != '\0') {
		UART0_Write_Byte(*str);
		str++;
	}
	if (*str == '%') {
		memset(buf, 0, 16);
		str++;
		switch (*str) {
			case 'u' : {
				cv = va_arg(va, unsigned long);
				while (cv / 10 != 0) {
					buf[index++] = cv % 10;
					cv /= 10;
				}
				buf[index] = cv / 10;
				while (index > 0) {
					index--;
					UART0_Write_Byte(hexToAsc[buf[index]]);
				}
			}
			break;

			case 'X' : {
				cv = va_arg(va, unsigned long);
				while (cv / 16 != 0) {
					buf[index++] = cv % 16;
					cv /= 16;
				}
				buf[index] = cv / 16;
				while (index > 0) {
					index--;
					UART0_Write_Byte(hexToAsc[buf[index]]);
				}
			}
			break;

			default : {
				
			}
		}
	}
	va_end(va);
	UART0_Write_Byte('\r');
	UART0_Write_Byte('\n');
}
#endif